package md.frolov.bible.converters;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

public class BQReferencess2XMLConverter {
	public final static String[] bookShortNamesEn = BQ2XMLConverter.bookShortNamesEn;
	public final static String path = "/home/gusto/.cxoffice/Unsupported/drive_c/BibleQuote/TSK";
	private static String outputPath="/home/gusto/Eclipse Workspace/runtimes/runtime-md.frolov.bible.product/books/";
	private static String encoding="Cp1251";
	
	private static Document dom;
	private static Element rootElement;
	
	private static int bookCounter = 0;
	private static int chapterCounter = 0;
	
	private static Map<String,String> nameMap = new HashMap<String,String>();
	
	public static void main(String[] args){
		initStrMap();
		initDocument();
		
		File f = new File(path);
		File[] list = f.listFiles();
		
		for (int i = 0; i < list.length; i++) {
			File file = list[i];
			try{
				parseFile(file);
			} catch (FileNotFoundException e){
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		XMLSerializer xmlSer;
		try {
			xmlSer = new XMLSerializer(new FileWriter(new File(outputPath+"references.refs"),false), new OutputFormat(dom,"UTF-8",false));
			xmlSer.serialize(dom);
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("Parsed");
	}
	
	public static void parseFile(File f) throws IOException{
		bookCounter++;
		chapterCounter = 0;
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f),encoding));
		String line;
		while((line=br.readLine())!=null){
			if(line.startsWith("[")){//new chapter
				chapterCounter=Integer.parseInt(line.substring(1,line.indexOf(']')));
				continue;
			}
			
			String[] str1 = line.split("=");
			if(str1.length<2){
//				System.out.println("Empty - "+chapterCounter+":"+str1[0]);
				continue;
			}
			
			String[] str2 = str1[1].trim().split(";");
			Element verse = dom.createElement("verse");
			verse.setAttribute("id", "bible."+bookShortNamesEn[bookCounter-1]+"."+chapterCounter+"."+str1[0]);
			rootElement.appendChild(verse);
			
			Pattern p  = Pattern.compile("([a-zA-Z0-9\\.]*) (\\d+):(\\d+)-?(\\d+)?");
			for (int i = 0; i < str2.length; i++) {
//				System.out.print("("+i+") "+str2[i]+", ");
				Matcher m = p.matcher(str2[i].trim());
				if(m.matches()){
					Element ref = dom.createElement("ref");
					verse.appendChild(ref);
					String bName = resolveBookName(m.group(1));
					ref.setAttribute("aId", "bible."+bName+"."+m.group(2)+"."+m.group(3));
					if(m.group(4) != null){
						ref.setAttribute("zId", "bible."+bName+"."+m.group(2)+"."+m.group(4));
					}
				} else {
					System.err.println("!no match: \""+str2[i]+"\"");
				}
			}
		}
		
	}
	
	public static String resolveBookName(String bookName){
		String ret = strMap.get(bookName);
		for(int i=0;i<bookShortNamesEn.length;i++){
			if(ret.equals(bookShortNamesEn[i])) return ret;
		}
		System.err.println("no such book: "+bookName);
		return null;
	}
	
	public static void initDocument(){
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
		//get an instance of builder
		DocumentBuilder db = dbf.newDocumentBuilder();

		//create an instance of DOM
		dom = db.newDocument();

		}catch(ParserConfigurationException pce) {
			//dump it
			System.out.println("Error while trying to instantiate DocumentBuilder " + pce);
			System.exit(1);
		}
		
		rootElement = dom.createElement("references");
		dom.appendChild(rootElement);
	}
	
	public static Map<String,String> strMap = new HashMap<String, String>();

	public static void initStrMap(){
		strMap.put("1",bookShortNamesEn[0]); //19_psalms.ini 119:97
		strMap.put("10",bookShortNamesEn[9]); //43_john.ini 8:18
		strMap.put("12",bookShortNamesEn[11]); //01_genesis.ini 46:22
		strMap.put("14",bookShortNamesEn[13]); //05_deuteronomy.ini 12:11
		strMap.put("141","psa"); //19_psalms.ini 119:29 ???
		strMap.put("15",bookShortNamesEn[14]); //24_jeremiah.ini 50:9
		strMap.put("17",bookShortNamesEn[16]); //03_leviticus.ini 11:24
		strMap.put("18",bookShortNamesEn[17]); //19_psalms.ini 119:101
		strMap.put("19",bookShortNamesEn[18]); //19_psalms.ini 119:86
		strMap.put("1Ch","1cr"); //66_revelations.ini 19:4
		strMap.put("1Co","1co"); //66_revelations.ini 22:17
		strMap.put("1Jo","1jn"); //66_revelations.ini 22:9
		strMap.put("1Ki","1ki"); //66_revelations.ini 21:22
		strMap.put("1Pe","1pe"); //66_revelations.ini 22:10
		strMap.put("1Sa","1sa"); //66_revelations.ini 19:18
		strMap.put("1Th","1th"); //66_revelations.ini 22:18
		strMap.put("1Ti","1ti"); //66_revelations.ini 19:16
		strMap.put("22",bookShortNamesEn[21]); //40_matthew.ini 13:3
		strMap.put("23",bookShortNamesEn[22]); //06_joshua.ini 24:10
		strMap.put("25",bookShortNamesEn[24]); //40_matthew.ini 22:2
		strMap.put("26",bookShortNamesEn[25]); //26_ezekiel.ini 27:27
		strMap.put("2Ch","2cr"); //66_revelations.ini 18:5
		strMap.put("2Co","2co"); //66_revelations.ini 22:21
		strMap.put("2Jo","2jn"); //64_3john.ini 1:13
		strMap.put("2Ki","2ki"); //66_revelations.ini 20:9
		strMap.put("2Pe","2pe"); //66_revelations.ini 22:16
		strMap.put("2Sa","2sa"); //66_revelations.ini 14:6
		strMap.put("2Th","2th"); //66_revelations.ini 19:20
		strMap.put("2Ti","2ti"); //66_revelations.ini 22:11
		strMap.put("3",bookShortNamesEn[2]); //21_ecclesiastes.ini 1:2
		strMap.put("30",bookShortNamesEn[29]); //09_1samuel.ini 27:3
		strMap.put("3Jo","3jn"); //64_3john.ini 1:9
		strMap.put("40",bookShortNamesEn[39]); //19_psalms.ini 119:16
		strMap.put("51",bookShortNamesEn[50]); //19_psalms.ini 119:124
		strMap.put("69",bookShortNamesEn[18]); //19_psalms.ini 119:41 //
		strMap.put("8",bookShortNamesEn[7]); //03_leviticus.ini 9:9
		strMap.put("Ac","act"); //66_revelations.ini 22:1
		strMap.put("Act","act"); //44_acts.ini 28:30
		strMap.put("Am","amo"); //66_revelations.ini 18:10
		strMap.put("Amo","amo"); //30_amos.ini 9:13
		strMap.put("Col","col"); //66_revelations.ini 13:10
		strMap.put("Da","dan"); //66_revelations.ini 19:19
		strMap.put("Dan","dan"); //27_daniel.ini 12:9
		strMap.put("De","deu"); //66_revelations.ini 22:3
		strMap.put("Deu","deu"); //05_deuteronomy.ini 34:12
		strMap.put("Ec","ecl"); //66_revelations.ini 11:9
		strMap.put("Ecc","ecl"); //21_ecclesiastes.ini 10:17
		strMap.put("Eph","eph"); //66_revelations.ini 10:2
		strMap.put("Es","est"); //59_james.ini 2:2
		strMap.put("Est","est"); //17_esther.ini 9:26
		strMap.put("Ex","exo"); //66_revelations.ini 22:19
		strMap.put("Exo","exo"); //02_exodus.ini 40:32
		strMap.put("Eze","eze"); //66_revelations.ini 21:16
		strMap.put("Ezr","ezr"); //40_matthew.ini 28:8
		strMap.put("Ga","gal"); //66_revelations.ini 12:2
		strMap.put("Gal","gal"); //48_galatians.ini 4:21
		strMap.put("Ge","gen"); //66_revelations.ini 19:3
		strMap.put("Gen","gen"); //01_genesis.ini 50:26
		strMap.put("Hab","hab"); //66_revelations.ini 8:1
		strMap.put("Hag","hag"); //43_john.ini 7:14
		strMap.put("Heb","heb"); //66_revelations.ini 19:11
		strMap.put("Ho","hos"); //46_1corinthians.ini 7:4
		strMap.put("Hos","hos"); //28_hosea.ini 2:12
		strMap.put("Isa","isa"); //66_revelations.ini 22:13
		strMap.put("Jam","jms"); //59_james.ini 3:11
		strMap.put("Jas","jms"); //59_james.ini 2:4
		strMap.put("Jdg","jdg"); //43_john.ini 4:37
		strMap.put("Jer","jer"); //66_revelations.ini 17:2
		strMap.put("Job","job"); //44_acts.ini 27:19
		strMap.put("Joe","joe"); //66_revelations.ini 14:18
		strMap.put("Joh","jhn"); //66_revelations.ini 14:16
		strMap.put("Jon","jhn"); //42_luke.ini 22:46
		strMap.put("Jos","jos"); //44_acts.ini 23:22
		strMap.put("Jude","jud"); //19_psalms.ini 1:5
		strMap.put("La","lam"); //42_luke.ini 13:18
		strMap.put("Lam","lam"); //25_lamentations.ini 3:62
		strMap.put("Le","lev"); //58_hebrew.ini 9:22 ???????
		strMap.put("Lev","lev"); //03_leviticus.ini 27:27
		strMap.put("Lu","luk"); //66_revelations.ini 22:19
		strMap.put("Luk","luk"); //42_luke.ini 24:42
		strMap.put("Mal","mal"); //41_mark.ini 9:11
		strMap.put("Mar","mar"); //41_mark.ini 14:59
		strMap.put("Mat","mat"); //40_matthew.ini 28:11
		strMap.put("Mic","mic"); //42_luke.ini 12:53
		strMap.put("Mr","mar"); //59_james.ini 3:7
		strMap.put("Mt","mat"); //66_revelations.ini 20:10
		strMap.put("Na","nau"); //26_ezekiel.ini 30:15
		strMap.put("Nah","nau"); //34_nahum.ini 3:15
		strMap.put("Ne","neh"); //24_jeremiah.ini 42:12
		strMap.put("Neh","neh"); //16_nehemia.ini 7:49
		strMap.put("Nu","num"); //42_luke.ini 1:21
		strMap.put("Num","num"); //04_numbers.ini 36:12
		strMap.put("Ob","oba"); //66_revelations.ini 11:10
		strMap.put("Oba","oba"); //31_obadiah.ini 1:18
		strMap.put("Phi","php"); //50_philippians.ini 4:20
		strMap.put("Phm","phm"); //58_hebrew.ini 13:19
		strMap.put("Php","php"); //47_2corinthians.ini 8:22
		strMap.put("Pr","pro"); //61_2peter.ini 2:22
		strMap.put("Pro","pro"); //20_proverbs.ini 29:17
		strMap.put("Ps","psa"); //66_revelations.ini 19:5
		strMap.put("Psa","psa"); //19_psalms.ini 150:6
		strMap.put("Re","rev"); //66_revelations.ini 22:8
		strMap.put("Rev","rev"); //66_revelations.ini 22:20
		strMap.put("Ro","rom"); //60_1peter.ini 2:14
		strMap.put("Rom","rom"); //45_romans.ini 16:9
		strMap.put("Ru","rut"); //13_1chronicles.ini 2:37
		strMap.put("Rut","rut"); //08_ruth.ini 4:6
		strMap.put("So","son"); //42_luke.ini 23:28
		strMap.put("Son","son"); //22_songofsolomon.ini 8:10
		strMap.put("Tit","tit"); //66_revelations.ini 19:9
		strMap.put("Zec","zec"); //38_zecharia.ini 8:1
		strMap.put("Zep","zep"); //16_nehemia.ini 13:24
	}
}